/**
 * 进程管理器 - Phase 2 增强版
 * EndoSight-UC 医疗AI系统
 *
 * 管理多进程AI推理工作器
 * 提供进程监控、自动重启、负载均衡和性能优化
 */

import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
import os from 'os';
import EventEmitter from 'events';
import winston from 'winston';
import path from 'path';
import fs from 'fs';
import crypto from 'crypto';
import { createRequire } from 'module';

const require = createRequire(import.meta.url);
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console({
      format: winston.format.combine(
        winston.format.colorize(),
        winston.format.simple()
      )
    })
  ]
});

/**
 * 工作器状态枚举
 */
export const WorkerStatus = {
  STARTING: 'starting',     // 启动中
  IDLE: 'idle',             // 空闲
  BUSY: 'busy',             // 忙碌
  OVERLOADED: 'overloaded', // 过载
  ERROR: 'error',           // 错误
  TERMINATING: 'terminating', // 终止中
  TERMINATED: 'terminated'  // 已终止
};

/**
 * 工作器类型枚举
 */
export const WorkerType = {
  AI_INFERENCE: 'ai_inference',       // AI推理工作器
  BATCH_PROCESSING: 'batch_processing', // 批处理工作器
  FILE_PROCESSING: 'file_processing',   // 文件处理工作器
  CLEANUP: 'cleanup',                  // 清理工作器
  MONITORING: 'monitoring'             // 监控工作器
};

/**
 * 工作器配置
 */
const WORKER_CONFIGS = {
  [WorkerType.AI_INFERENCE]: {
    maxWorkers: Math.min(os.cpus().length, 4), // 最多4个AI推理进程
    maxMemoryMB: 2048,                         // 最大内存限制2GB
    maxTasksPerWorker: 50,                     // 每个工作器最大任务数
    restartDelay: 5000,                        // 重启延迟5秒
    healthCheckInterval: 30000,                // 健康检查间隔30秒
    taskTimeout: 60000,                        // 任务超时60秒
    priority: 10                               // 高优先级
  },
  [WorkerType.BATCH_PROCESSING]: {
    maxWorkers: Math.min(os.cpus().length - 1, 2), // 批处理进程
    maxMemoryMB: 1024,
    maxTasksPerWorker: 20,
    restartDelay: 10000,
    healthCheckInterval: 60000,
    taskTimeout: 300000, // 5分钟超时
    priority: 5
  },
  [WorkerType.FILE_PROCESSING]: {
    maxWorkers: 2,
    maxMemoryMB: 512,
    maxTasksPerWorker: 100,
    restartDelay: 3000,
    healthCheckInterval: 30000,
    taskTimeout: 30000,
    priority: 3
  },
  [WorkerType.CLEANUP]: {
    maxWorkers: 1,
    maxMemoryMB: 256,
    maxTasksPerWorker: 1000,
    restartDelay: 15000,
    healthCheckInterval: 120000,
    taskTimeout: 600000, // 10分钟
    priority: 1
  },
  [WorkerType.MONITORING]: {
    maxWorkers: 1,
    maxMemoryMB: 128,
    maxTasksPerWorker: 100,
    restartDelay: 30000,
    healthCheckInterval: 60000,
    taskTimeout: 10000,
    priority: 1
  }
};

/**
 * 工作器进程信息
 */
class WorkerProcess {
  constructor(type, id, config) {
    this.id = id;
    this.type = type;
    this.config = config;
    this.status = WorkerStatus.STARTING;
    this.worker = null;
    this.startTime = Date.now();
    this.lastActivity = Date.now();
    this.taskCount = 0;
    this.errorCount = 0;
    this.memoryUsage = 0;
    this.cpuUsage = 0;
    this.currentTask = null;
    this.healthScore = 100;
    this.restartCount = 0;
    this.lastRestart = null;
    this.correlationId = crypto.randomUUID();
  }

  /**
   * 启动工作器进程
   */
  async start() {
    try {
      logger.info(`启动工作器进程: ${this.type}_${this.id}`, {
        workerId: this.id,
        type: this.type,
        correlationId: this.correlationId
      });

      // 构建工作器脚本路径
      const workerScript = this.getWorkerScriptPath();

      // 准备工作器数据
      const workerData = {
        workerId: this.id,
        type: this.type,
        config: this.config,
        correlationId: this.correlationId,
        startTime: Date.now()
      };

      // 创建工作器线程
      this.worker = new Worker(workerScript, {
        workerData,
        resourceLimits: {
          maxOldGenerationSizeMb: this.config.maxMemoryMB,
          maxYoungGenerationSizeMb: 256
        }
      });

      // 设置事件监听
      this.setupEventListeners();

      this.status = WorkerStatus.IDLE;
      this.lastActivity = Date.now();

      logger.info(`工作器进程启动成功: ${this.type}_${this.id}`, {
        workerId: this.id,
        pid: this.worker.threadId,
        correlationId: this.correlationId
      });

      return true;
    } catch (error) {
      logger.error(`工作器进程启动失败: ${this.type}_${this.id}`, {
        workerId: this.id,
        error: error.message,
        correlationId: this.correlationId
      });

      this.status = WorkerStatus.ERROR;
      throw error;
    }
  }

  /**
   * 获取工作器脚本路径
   */
  getWorkerScriptPath() {
    const scriptMap = {
      [WorkerType.AI_INFERENCE]: 'aiInferenceWorkerThread.js',
      [WorkerType.BATCH_PROCESSING]: 'batchProcessingWorkerThread.js',
      [WorkerType.FILE_PROCESSING]: 'fileProcessingWorkerThread.js',
      [WorkerType.CLEANUP]: 'cleanupWorkerThread.js',
      [WorkerType.MONITORING]: 'monitoringWorkerThread.js'
    };

    const scriptName = scriptMap[this.type];
    if (!scriptName) {
      throw new Error(`未知的工作器类型: ${this.type}`);
    }

    return path.join(__dirname, 'workers', 'threads', scriptName);
  }

  /**
   * 设置事件监听器
   */
  setupEventListeners() {
    // 监听工作器消息
    this.worker.on('message', (message) => {
      this.handleWorkerMessage(message);
    });

    // 监听工作器错误
    this.worker.on('error', (error) => {
      this.handleWorkerError(error);
    });

    // 监听工作器退出
    this.worker.on('exit', (code, signal) => {
      this.handleWorkerExit(code, signal);
    });

    // 监听在线消息
    this.worker.on('online', () => {
      logger.debug(`工作器在线: ${this.type}_${this.id}`, {
        workerId: this.id,
        threadId: this.worker.threadId
      });
    });
  }

  /**
   * 处理工作器消息
   */
  handleWorkerMessage(message) {
    this.lastActivity = Date.now();

    switch (message.type) {
      case 'task_started':
        this.status = WorkerStatus.BUSY;
        this.currentTask = message.task;
        this.taskCount++;
        break;

      case 'task_completed':
        this.status = WorkerStatus.IDLE;
        this.currentTask = null;
        this.healthScore = Math.min(100, this.healthScore + 1);
        break;

      case 'task_failed':
        this.status = WorkerStatus.IDLE;
        this.currentTask = null;
        this.errorCount++;
        this.healthScore = Math.max(0, this.healthScore - 5);
        break;

      case 'status_update':
        this.memoryUsage = message.memoryUsage || 0;
        this.cpuUsage = message.cpuUsage || 0;
        this.healthScore = message.healthScore || 100;
        break;

      case 'overloaded':
        this.status = WorkerStatus.OVERLOADED;
        break;

      default:
        logger.debug(`未知消息类型: ${message.type}`, {
          workerId: this.id,
          messageType: message.type
        });
    }
  }

  /**
   * 处理工作器错误
   */
  handleWorkerError(error) {
    logger.error(`工作器错误: ${this.type}_${this.id}`, {
      workerId: this.id,
      error: error.message,
      stack: error.stack,
      correlationId: this.correlationId
    });

    this.errorCount++;
    this.healthScore = Math.max(0, this.healthScore - 10);
    this.status = WorkerStatus.ERROR;
  }

  /**
   * 处理工作器退出
   */
  handleWorkerExit(code, signal) {
    logger.warn(`工作器退出: ${this.type}_${this.id}`, {
      workerId: this.id,
      exitCode: code,
      exitSignal: signal,
      uptime: Date.now() - this.startTime,
      taskCount: this.taskCount,
      errorCount: this.errorCount,
      correlationId: this.correlationId
    });

    this.status = WorkerStatus.TERMINATED;
    this.worker = null;
  }

  /**
   * 分配任务
   */
  async assignTask(task) {
    if (this.status !== WorkerStatus.IDLE || !this.worker) {
      throw new Error(`工作器不可用: ${this.type}_${this.id} (${this.status})`);
    }

    this.worker.postMessage({
      type: 'assign_task',
      task: {
        ...task,
        assignedAt: Date.now(),
        workerId: this.id
      }
    });

    this.currentTask = task;
    this.status = WorkerStatus.BUSY;
    this.lastActivity = Date.now();
  }

  /**
   * 获取工作器状态
   */
  getStatus() {
    return {
      id: this.id,
      type: this.type,
      status: this.status,
      startTime: this.startTime,
      lastActivity: this.lastActivity,
      taskCount: this.taskCount,
      errorCount: this.errorCount,
      memoryUsage: this.memoryUsage,
      cpuUsage: this.cpuUsage,
      healthScore: this.healthScore,
      restartCount: this.restartCount,
      lastRestart: this.lastRestart,
      uptime: Date.now() - this.startTime,
      currentTask: this.currentTask,
      correlationId: this.correlationId,
      threadId: this.worker?.threadId || null
    };
  }

  /**
   * 健康检查
   */
  async healthCheck() {
    if (!this.worker || this.status === WorkerStatus.TERMINATED) {
      return false;
    }

    try {
      // 发送健康检查消息
      this.worker.postMessage({
        type: 'health_check',
        timestamp: Date.now()
      });

      // 检查响应时间
      const responseTime = Date.now() - this.lastActivity;
      if (responseTime > this.config.healthCheckInterval) {
        this.healthScore = Math.max(0, this.healthScore - 5);
        return false;
      }

      // 检查错误率
      const errorRate = this.taskCount > 0 ? this.errorCount / this.taskCount : 0;
      if (errorRate > 0.1) { // 错误率超过10%
        this.healthScore = Math.max(0, this.healthScore - 15);
      }

      // 检查内存使用
      if (this.memoryUsage > this.config.maxMemoryMB * 0.9) {
        this.healthScore = Math.max(0, this.healthScore - 10);
      }

      return this.healthScore > 50;
    } catch (error) {
      logger.error(`健康检查失败: ${this.type}_${this.id}`, {
        workerId: this.id,
        error: error.message
      });
      return false;
    }
  }

  /**
   * 终止工作器
   */
  async terminate() {
    this.status = WorkerStatus.TERMINATING;

    if (this.worker) {
      try {
        // 发送优雅关闭消息
        this.worker.postMessage({
          type: 'shutdown',
          timestamp: Date.now()
        });

        // 等待5秒优雅关闭
        await new Promise((resolve, reject) => {
          const timeout = setTimeout(() => {
            reject(new Error('工作器关闭超时'));
          }, 5000);

          this.worker.once('exit', () => {
            clearTimeout(timeout);
            resolve();
          });
        });
      } catch (error) {
        logger.warn(`优雅关闭失败，强制终止: ${this.type}_${this.id}`, {
          workerId: this.id,
          error: error.message
        });

        // 强制终止
        this.worker.terminate();
      }
    }

    this.status = WorkerStatus.TERMINATED;
    this.worker = null;
  }

  /**
   * 重启工作器
   */
  async restart() {
    logger.info(`重启工作器: ${this.type}_${this.id}`, {
      workerId: this.id,
      restartCount: this.restartCount + 1
    });

    await this.terminate();

    // 等待重启延迟
    await new Promise(resolve => setTimeout(resolve, this.config.restartDelay));

    this.restartCount++;
    this.lastRestart = Date.now();
    this.taskCount = 0;
    this.errorCount = 0;
    this.healthScore = 100;
    this.currentTask = null;

    await this.start();
  }
}

/**
 * 进程管理器主类
 */
export class ProcessManager extends EventEmitter {
  constructor() {
    super();
    this.workers = new Map(); // workerId -> WorkerProcess
    this.workerTypes = new Map(); // type -> Map<workerId, WorkerProcess>
    this.isRunning = false;
    this.startTime = null;
    this.totalTasksProcessed = 0;
    this.totalErrors = 0;
    this.metricsInterval = null;
    this.healthCheckInterval = null;
    this.correlationId = crypto.randomUUID();
  }

  /**
   * 初始化进程管理器
   */
  async initialize() {
    if (this.isRunning) {
      logger.warn('进程管理器已在运行中');
      return;
    }

    logger.info('🚀 初始化进程管理器', {
      correlationId: this.correlationId,
      nodeVersion: process.version,
      platform: os.platform(),
      arch: os.arch(),
      cpus: os.cpus().length,
      totalMemoryMB: Math.round(os.totalmem() / 1024 / 1024)
    });

    this.startTime = Date.now();
    this.isRunning = true;

    // 启动所有类型的工作器
    for (const [type, config] of Object.entries(WORKER_CONFIGS)) {
      await this.startWorkerType(type, config);
    }

    // 启动监控任务
    this.startMonitoring();

    logger.info('✅ 进程管理器初始化完成', {
      correlationId: this.correlationId,
      totalWorkers: this.workers.size,
      workerTypes: Array.from(this.workerTypes.keys()),
      startTime: this.startTime
    });

    this.emit('initialized', {
      totalWorkers: this.workers.size,
      correlationId: this.correlationId
    });
  }

  /**
   * 启动特定类型的工作器
   */
  async startWorkerType(type, config) {
    logger.info(`启动工作器类型: ${type}`, {
      type,
      maxWorkers: config.maxWorkers,
      correlationId: this.correlationId
    });

    const workerMap = new Map();
    this.workerTypes.set(type, workerMap);

    for (let i = 0; i < config.maxWorkers; i++) {
      try {
        const workerProcess = new WorkerProcess(type, i, config);
        await workerProcess.start();

        workerMap.set(i, workerProcess);
        this.workers.set(`${type}_${i}`, workerProcess);

        // 添加事件监听
        workerProcess.on('status_change', (status) => {
          this.emit('worker_status_change', {
            workerId: workerProcess.id,
            type,
            status
          });
        });

      } catch (error) {
        logger.error(`启动工作器失败: ${type}_${i}`, {
          type,
          workerId: i,
          error: error.message
        });
      }
    }

    logger.info(`工作器类型启动完成: ${type}`, {
      type,
      successfulWorkers: workerMap.size,
      expectedWorkers: config.maxWorkers,
      correlationId: this.correlationId
    });
  }

  /**
   * 启动监控任务
   */
  startMonitoring() {
    // 指标收集任务
    this.metricsInterval = setInterval(() => {
      this.collectMetrics();
    }, 30000); // 每30秒收集一次指标

    // 健康检查任务
    this.healthCheckInterval = setInterval(() => {
      this.performHealthChecks();
    }, 60000); // 每分钟进行一次健康检查

    logger.info('监控任务已启动', {
      metricsInterval: 30000,
      healthCheckInterval: 60000,
      correlationId: this.correlationId
    });
  }

  /**
   * 收集指标
   */
  collectMetrics() {
    const metrics = {
      timestamp: Date.now(),
      correlationId: this.correlationId,
      uptime: Date.now() - this.startTime,
      totalWorkers: this.workers.size,
      totalTasksProcessed: this.totalTasksProcessed,
      totalErrors: this.totalErrors,
      workersByType: {},
      systemMetrics: {
        memoryUsage: process.memoryUsage(),
        cpuUsage: process.cpuUsage(),
        platform: os.platform(),
        loadAverage: os.loadavg(),
        freeMemoryMB: Math.round(os.freemem() / 1024 / 1024),
        totalMemoryMB: Math.round(os.totalmem() / 1024 / 1024)
      }
    };

    // 收集每个工作器的指标
    for (const [type, workerMap] of this.workerTypes) {
      const typeMetrics = {
        count: workerMap.size,
        busy: 0,
        idle: 0,
        error: 0,
        overloaded: 0,
        averageHealthScore: 0,
        totalTasks: 0,
        totalErrors: 0,
        averageMemoryUsage: 0
      };

      let totalHealthScore = 0;
      let totalMemoryUsage = 0;

      for (const worker of workerMap.values()) {
        const status = worker.getStatus();

        switch (status.status) {
          case WorkerStatus.BUSY:
            typeMetrics.busy++;
            break;
          case WorkerStatus.IDLE:
            typeMetrics.idle++;
            break;
          case WorkerStatus.ERROR:
            typeMetrics.error++;
            break;
          case WorkerStatus.OVERLOADED:
            typeMetrics.overloaded++;
            break;
        }

        totalHealthScore += status.healthScore;
        totalMemoryUsage += status.memoryUsage;
        typeMetrics.totalTasks += status.taskCount;
        typeMetrics.totalErrors += status.errorCount;
      }

      if (workerMap.size > 0) {
        typeMetrics.averageHealthScore = Math.round(totalHealthScore / workerMap.size);
        typeMetrics.averageMemoryUsage = Math.round(totalMemoryUsage / workerMap.size);
      }

      metrics.workersByType[type] = typeMetrics;
    }

    this.emit('metrics_collected', metrics);

    logger.debug('指标收集完成', {
      correlationId: this.correlationId,
      totalWorkers: metrics.totalWorkers,
      totalTasksProcessed: metrics.totalTasksProcessed
    });
  }

  /**
   * 执行健康检查
   */
  async performHealthChecks() {
    const healthResults = {
      timestamp: Date.now(),
      correlationId: this.correlationId,
      totalWorkers: this.workers.size,
      healthyWorkers: 0,
      unhealthyWorkers: 0,
      restartedWorkers: 0,
      details: []
    };

    for (const [workerId, worker] of this.workers) {
      try {
        const isHealthy = await worker.healthCheck();

        if (isHealthy) {
          healthResults.healthyWorkers++;
        } else {
          healthResults.unhealthyWorkers++;

          // 如果健康评分太低，重启工作器
          if (worker.healthScore < 30 && worker.restartCount < 3) {
            logger.warn(`重启不健康的工作器: ${workerId}`, {
              workerId,
              healthScore: worker.healthScore,
              restartCount: worker.restartCount
            });

            await worker.restart();
            healthResults.restartedWorkers++;
          }
        }

        healthResults.details.push({
          workerId,
          type: worker.type,
          status: worker.status,
          healthScore: worker.healthScore,
          isHealthy
        });

      } catch (error) {
        logger.error(`健康检查异常: ${workerId}`, {
          workerId,
          error: error.message
        });

        healthResults.unhealthyWorkers++;
      }
    }

    this.emit('health_check_completed', healthResults);

    logger.info('健康检查完成', {
      correlationId: this.correlationId,
      healthyWorkers: healthResults.healthyWorkers,
      unhealthyWorkers: healthResults.unhealthyWorkers,
      restartedWorkers: healthResults.restartedWorkers
    });
  }

  /**
   * 分配任务到最佳工作器
   */
  async assignTask(type, task) {
    const workerMap = this.workerTypes.get(type);
    if (!workerMap || workerMap.size === 0) {
      throw new Error(`没有可用的工作器类型: ${type}`);
    }

    // 找到最佳工作器（空闲且健康评分最高）
    let bestWorker = null;
    let bestScore = -1;

    for (const worker of workerMap.values()) {
      if (worker.status === WorkerStatus.IDLE && worker.healthScore > 50) {
        const score = worker.healthScore - (worker.taskCount * 0.1); // 考虑任务负载
        if (score > bestScore) {
          bestScore = score;
          bestWorker = worker;
        }
      }
    }

    if (!bestWorker) {
      throw new Error(`没有可用的${type}工作器`);
    }

    try {
      await bestWorker.assignTask(task);
      this.totalTasksProcessed++;

      logger.info(`任务已分配: ${type}_${bestWorker.id}`, {
        workerId: bestWorker.id,
        type,
        taskId: task.id,
        correlationId: this.correlationId
      });

      return bestWorker.id;
    } catch (error) {
      this.totalErrors++;
      throw error;
    }
  }

  /**
   * 获取系统状态
   */
  getSystemStatus() {
    const status = {
      isRunning: this.isRunning,
      startTime: this.startTime,
      uptime: this.startTime ? Date.now() - this.startTime : 0,
      correlationId: this.correlationId,
      totalWorkers: this.workers.size,
      totalTasksProcessed: this.totalTasksProcessed,
      totalErrors: this.totalErrors,
      workersByType: {},
      systemInfo: {
        nodeVersion: process.version,
        platform: os.platform(),
        arch: os.arch(),
        cpus: os.cpus().length,
        totalMemoryMB: Math.round(os.totalmem() / 1024 / 1024),
        freeMemoryMB: Math.round(os.freemem() / 1024 / 1024),
        loadAverage: os.loadavg()
      }
    };

    for (const [type, workerMap] of this.workerTypes) {
      status.workersByType[type] = {
        count: workerMap.size,
        workers: Array.from(workerMap.values()).map(w => w.getStatus())
      };
    }

    return status;
  }

  /**
   * 关闭进程管理器
   */
  async shutdown() {
    logger.info('🛑 关闭进程管理器', {
      correlationId: this.correlationId,
      totalWorkers: this.workers.size
    });

    this.isRunning = false;

    // 清理监控任务
    if (this.metricsInterval) {
      clearInterval(this.metricsInterval);
      this.metricsInterval = null;
    }

    if (this.healthCheckInterval) {
      clearInterval(this.healthCheckInterval);
      this.healthCheckInterval = null;
    }

    // 关闭所有工作器
    const shutdownPromises = Array.from(this.workers.values()).map(async worker => {
      try {
        await worker.terminate();
      } catch (error) {
        logger.error(`关闭工作器失败: ${worker.type}_${worker.id}`, {
          workerId: worker.id,
          error: error.message
        });
      }
    });

    await Promise.all(shutdownPromises);

    this.workers.clear();
    this.workerTypes.clear();

    logger.info('✅ 进程管理器已关闭', {
      correlationId: this.correlationId,
      totalUptime: Date.now() - this.startTime,
      totalTasksProcessed: this.totalTasksProcessed,
      totalErrors: this.totalErrors
    });

    this.emit('shutdown', {
      correlationId: this.correlationId,
      totalUptime: Date.now() - this.startTime,
      totalTasksProcessed: this.totalTasksProcessed
    });
  }
}

// 创建全局进程管理器实例
export const processManager = new ProcessManager();

export default processManager;